package model.lights;

import java.awt.Color;

import javax.vecmath.Point3d;

public class PointLight extends Light {
	public ContextFallOff falloff = new ContextFallOff(1);
	// for grid lights
	private static final double [] delta = {0, -1, 1}; 	
	
	/**
	 * La componente especular de la luz para este constructor = la componente diffuse
	 * @param diffuseColor Color de la componente diffuse de la luz
	 * @param power intensidad de la luz
	 * @param source origen de la luz en el escenario
	 * @param falloffmode Tipo de algoritmo de falloff a utilizar, 0: linear, 1: raiz inversa
	 */
	public PointLight(Color diffuseColor, float power, Point3d source) {
		this.diffuseColor = diffuseColor;
		this.power = power;
		this.source = source;
		//this.falloff = new ContextFallOff(1); // por default es cuadratico fall off
		this.gridLight = createGridLights();
	}
	
	public PointLight() {
	}

	private Light[] createGridLights() {
		int rows = delta.length;
		int columns = delta.length;
		
		Light[] ret = new Light[rows*columns];	
		
		int index = 0;
		for (int i = 0; i < rows; i++) {
			for (int j = 0; j < columns; j++) {
				PointLight light = new PointLight();
				Point3d p = new Point3d(source);
				p.x += delta[i];
				p.z += delta [j];
				light.source = p;
				light.ambientColor = ambientColor;
				light.diffuseColor = diffuseColor;

				light.power = this.power/(rows*columns);
				if (delta[j] == 0.0 && delta[i] == 0.0) {
					light.isGrid = false;
				} else {
					
					light.isGrid = true;
				}
				
				ret[index] = light;
				index++;
			}
		}
		
		
		return ret;
	}

	/**
	 * 
	 * @param mode 0: linear falloff, 1: inverse square law fall off (aka quadratic fall off)
	 */
	
	public void setFallOff(int mode) {
		if (mode < 0 || mode > 1) {
			throw new IllegalArgumentException("Invalid mode, must be 0 r 1");
		}
		
		this.falloff.changeFallOff(mode);
	}
	
	@Override
	public float getAttenuation(double distance) {
		return (float)this.falloff.getIntensityByDistance(distance);
	}
	

	@Override
	public String toString() {
		StringBuffer sb = new StringBuffer();
		sb.append("Light\n");
		sb.append("type: point");
		sb.append("diff: " + diffuseColor).append("\n");
		sb.append("ambient: " + ambientColor).append("\n");
		sb.append("power: " + power).append("\n");
		sb.append("source: " + source).append("\n");
		return sb.toString();
	}
}